package com.hotel.BL;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.EntityName;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;

import data.POS;
import data.UserLevel;
import data.passingData.UserLevelData;

public class UserLevelLogic extends AbstractBL {
	
	public UserLevelLogic(HttpServletRequest req,HttpServletResponse resp){
		this.req = req;
		this.resp = resp;
	}

	public List<UserLevel> GenerateUserLevel(long hotelId)
	{
		List<POS> counter = new POSLogic(req,resp).GetAllPOS(hotelId);
		List<UserLevel> list = new ArrayList<UserLevel>();
		
		String allcounter = "";
		
		for(int i=0;i<counter.size();i++){
			allcounter += counter.get(i).getId()+",";
		}
		allcounter = allcounter.substring(0, allcounter.length()-1);
				
		UserLevel userLevel = new UserLevel();
		
		if(GetUserLevel(hotelId,"Admin") == null)
		{
			userLevel = new UserLevel();
			userLevel.setHotelId(hotelId);
			userLevel.setTitle("Admin");
			userLevel.setWorkAreasString(allcounter);
			userLevel.setDefaultWorkAreasString(String.valueOf(counter.get(0).getId()));
			userLevel.setAvaliable(true);
			userLevel.setStatus(true);
			userLevel.setShortHotelCode(true);
			userLevel.setAdminAllowed(true);
			userLevel.setHousekeepingAllowed(true);
			list.add(userLevel);
			
		}else{
			userLevel = GetUserLevel(hotelId,"Admin");
			userLevel.setWorkAreasString(allcounter);
			userLevel.setDefaultWorkAreasString(String.valueOf(counter.get(0).getId()));
			userLevel.setShortHotelCode(true);
			list.add(userLevel);
		}
		
		if(GetUserLevel(hotelId,"Normal") == null){
			userLevel = new UserLevel();
			userLevel.setHotelId(hotelId);
			userLevel.setTitle("Normal");
			userLevel.setWorkAreasString(""+counter.get(0).getId());
			userLevel.setAvaliable(true);
			userLevel.setStatus(true);
			userLevel.setDefaultWorkAreasString(String.valueOf(counter.get(0).getId()));
			userLevel.setShortHotelCode(false);
			userLevel.setAdminAllowed(true);
			userLevel.setHousekeepingAllowed(true);
			list.add(userLevel);
		}else{
			userLevel = GetUserLevel(hotelId,"Normal");
			userLevel.setWorkAreasString(""+counter.get(0).getId());
			userLevel.setDefaultWorkAreasString(String.valueOf(counter.get(0).getId()));
			userLevel.setShortHotelCode(false);
			list.add(userLevel);
		}
		return list;
	}
	
	public UserLevel GetUserLevel(long hotelId,String title)
	{
		Query q = new Query(EntityName.UserLevel);
		
		Filter filterTitle = new FilterPredicate("title",FilterOperator.EQUAL,title);
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		
		Filter filters = CompositeFilterOperator.and(filterHotel, filterTitle);
		q.setFilter(filters);
		
		return GetUserLevel(datastore.prepare(q).asSingleEntity());
	}
	
	public UserLevel GetUserLevel(Entity entity)
	{
		if(entity == null) return null;
		UserLevel item = new UserLevel();
		item.setEntity(entity);
		return item;
	}
	
	public List<UserLevel> GetList(List<Entity> entities)
	{
		List<UserLevel> list = new ArrayList<UserLevel>();
		if(entities != null)
			for(Entity e : entities)
			{
				UserLevel t = new UserLevel();
				t.setEntity(e);
				list.add(t);
			}
		return list;
	}
	
	public List<UserLevel> GetAllUserLevel4AdminLimit(long hotelId,long offset,long line)
	{
		Query q = new Query(EntityName.UserLevel);
		
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterAvaliable = new FilterPredicate("avaliable",FilterOperator.EQUAL,true);

		Filter filter = CompositeFilterOperator.and(filterHotel, filterAvaliable);
		
		q.setFilter(filter);
		
		return GetList(datastore.prepare(q).asList(FetchOptions.Builder.withLimit((int) line).offset((int)offset)));
	}
	
	
	public List<UserLevel> GetAllUserLevel4Admin(long hotelId)
	{
		Query q = new Query(EntityName.UserLevel);
		
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterAvaliable = new FilterPredicate("avaliable",FilterOperator.EQUAL,true);

		Filter filter = CompositeFilterOperator.and(filterHotel, filterAvaliable);
		
		q.setFilter(filter);
		
		return GetList(datastore.prepare(q).asList(FetchOptions.Builder.withDefaults()));
	}
	
	public List<UserLevelData> SetToData(List<UserLevel> lv){
		List<UserLevelData> lvData = new ArrayList<UserLevelData>();
		for(int i=0;i<lv.size();i++){
			UserLevelData data = new UserLevelData();
			data.setId(lv.get(i).getId());
			data.setDefaultArea(lv.get(i).getDefaultWorkAreas().getTitle());
			data.setStatus(lv.get(i).isStatus());
			data.setTitle(lv.get(i).getTitle());
			List<String> workAreas = new ArrayList<String>();
			for(int x=0;x<lv.get(i).getWorkAreas().size();x++){
				workAreas.add(lv.get(i).getWorkAreas().get(x).getTitle());
			}
			data.setWorkAreas(workAreas);
			lvData.add(data);
		}
		return lvData;
	}
	
	public UserLevel ChangeStatus(long amenId) throws EntityNotFoundException{
		
		UserLevel a = GetUserLevel(amenId);
		if(a.isStatus() == true){
			a.setStatus(false);
		}else if(a.isStatus() == false){
			a.setStatus(true);
		}
		 
		Key k = datastore.put(a.getEntity());
		a.setId(k.getId());
		a.setKey(k);
		return a;
	}
	
	public UserLevel GetUserLevel(long id) {
		Key key = KeyFactory.createKey(EntityName.UserLevel, id);
		try {
			Entity lang = datastore.get(key);
			UserLevel c = new UserLevel();
			c.setEntity(lang);
			return c;
		} catch (EntityNotFoundException e) {
			return null;
		}
	}
	
	public UserLevel DeleteUserLevel(long id) throws EntityNotFoundException{
		UserLevel t = GetUserLevel(id);
		t.setAvaliable(false);
		t.setStatus(false);
		
		Key k = datastore.put(t.getEntity());
		t.setId(k.getId());
		t.setKey(k);

		return t;
	}
	
	public UserLevel AddUserLevel(long id,String title,String defaultcounter,String areas,boolean canShort,boolean adminAllowed,boolean housekeepingAllowed) throws EntityNotFoundException{
		UserLevel a = new UserLevel();
		
		a.setHotelId(id);
		a.setTitle(title);
		a.setDefaultWorkAreasString(defaultcounter);
		a.setWorkAreasString(areas);
		a.setShortHotelCode(canShort);
		a.setAdminAllowed(adminAllowed);
		a.setHousekeepingAllowed(housekeepingAllowed);
		a.setAvaliable(true);
		a.setStatus(true);
		
		Key k = datastore.put(a.getEntity());
		a.setId(k.getId());
		a.setKey(k);

		return a;
	}
	
	public UserLevel EditUserLevel(long id,String title,String defaultcounter,String areas,boolean canShort) throws EntityNotFoundException{
		UserLevel a = GetUserLevel(id);
		a.setTitle(title);
		a.setDefaultWorkAreasString(defaultcounter);
		a.setWorkAreasString(areas);
		a.setShortHotelCode(canShort);
		a.setAvaliable(true);
		a.setStatus(true);
		
		Key k = datastore.put(a.getEntity());
		a.setId(k.getId());
		a.setKey(k);

		return a;
	}
	
	public List<HashMap<String,Object>> OnlyIdAndTitle(List<UserLevel> list){
		List<HashMap<String,Object>> data = new ArrayList<HashMap<String,Object>>();
		for(int i=0;i<list.size();i++){
			HashMap<String,Object> map = new HashMap<String, Object>();
			map.put("id", list.get(i).getId());
			map.put("title", list.get(i).getTitle());
			data.add(map);
		}
		return data;
	}
}
